from google.appengine.ext import db
import random

class SeqListCounterShard(db.Model):    
    count = db.IntegerProperty(required=True, default=0)
      
class PostCounterShard(db.Model):
    count=db.IntegerProperty(required=True, default=0)

class TopicCounterShard(db.Model):
    count=db.IntegerProperty(required=True, default=0)
    
class UserCounterShard(db.Model):
    count=db.IntegerProperty(required=True, default=0)
        
class MailedCounterShard(db.Model):
    count=db.IntegerProperty(required=True, default=0)
            
class ForumCounterShard(db.Model):
    count=db.IntegerProperty(required=True, default=0)
    
class Counter:
    NUM_SHARDS = 5
    Shard=None
    
    def get(self):
        """Retrieve the value for a given sharded counter."""
        total = 0
        for counter in self.Shard.all():
            total += counter.count
        
        return total

    
    def inc(self):
        self._inc()
        return self.get()
                
    
    def _inc (self):
        """Increment the value for a given sharded counter."""
        def txn():
            index = random.randint(0, Counter.NUM_SHARDS - 1)
            shard_name = "shard" + str(index)
            counter = self.Shard.get_by_key_name(shard_name)
            if counter is None:
                counter = self.Shard(key_name=shard_name)
            counter.count += 1
            counter.put()
            #print "shard:%s,count %s"%(shard_name,counter.count)
            #return counter.count
        db.run_in_transaction(txn)
        
    
    def reset(self,base=0):
        for counter in self.Shard.all():
            counter.delete()
        index = random.randint(0, self.NUM_SHARDS - 1)
        shard_name = "shard" + str(index)
        counter =self.Shard(key_name=shard_name)
        counter.count=base
        counter.put()
        return




    
class SeqListCounter(Counter):
    NUM_SHARDS  =2
    Shard       =SeqListCounterShard
    
#in gate,PostCounter used to trace the current Post's seq to read in bot     
class PostCounter(Counter):
    NUM_SHARDS  =3
    Shard       =PostCounterShard
    
class TopicCounter(Counter):
    NUM_SHARDS  =3
    Shard       =TopicCounterShard
    
class ForumCounter(Counter):
    NUM_SHARDS  =3
    Shard       =ForumCounterShard
    

class UserCounter(Counter):
    NUM_SHARDS  =2
    Shard       =UserCounterShard

#mailed Counter used to mark the mailed PostTask
class MailedCounter(Counter):
    NUM_SHARDS  =2
    Shard       =MailedCounterShard
    

def main():
    uc=UserCounter()
    print uc.inc_and_get()

if __name__ == '__main__':
    main()       